package cn.livingCloud.service.impl;

import cn.livingCloud.context.Config;
import cn.livingCloud.context.SessionConstants;
import cn.livingCloud.dto.*;
import cn.livingCloud.dto.front.CaseAccusationFrontFromDto;
import cn.livingCloud.dto.front.CaseAssignmentFrontFormDto;
import cn.livingCloud.dto.front.CaseFinishFrontFormDto;
import cn.livingCloud.dto.front.MyCaseFrontListDto;
import cn.livingCloud.entity.core.*;
import cn.livingCloud.entity.system.Setting;
import cn.livingCloud.entity.user.Member;
import cn.livingCloud.repository.*;
import cn.livingCloud.service.CaseService;
import cn.livingCloud.service.impl.operation.*;
import cn.livingCloud.utils.SessionUtils;
import cn.livingCloud.wechat.protocol.JsSDKSignature;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Created by DingJie on 2016/6/2.
 */
@Service
public class CaseServiceImpl implements CaseService {
    @Autowired
    private CaseMapper mapper;
    @Autowired
    private CaseImageMapper imageMapper;
    @Autowired
    private CaseRecordMapper recordMapper;
    @Autowired
    private CaseCommentsMapper commentsMapper;
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private CaseCategoryMapper caseCategoryMapper;
    @Autowired
    private ReplySetMapper replySetMapper;
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private SettingMapper settingMapper;

    @Override
    public void loadCaseList(CaseListDto listDto) {
        CaseListDtoLoader loader = new CaseListDtoLoader(listDto);
        loader.load();
    }

    @Override
    public CaseFormDto loadCaseFromDto(String uuid, String creatorUuid) {
        CaseFormDto formDto;
        if (StringUtils.isNotEmpty(uuid)) {
            Case aCase = mapper.selectByPrimaryKey(uuid);
            formDto = new CaseFormDto(aCase);
        } else {
            formDto = new CaseFormDto();
            if (StringUtils.isNotEmpty(creatorUuid)) {
                Member member = memberMapper.findMemberByUuid(creatorUuid);
                formDto.setCreator(new MemberDto(member));
                formDto.setCreatorUuid(creatorUuid);
            }
        }
        return formDto;
    }

    @Override
    public void edit(CaseFormDto formDto) {
        CaseFormDtoUpdater updater = new CaseFormDtoUpdater(formDto);
        updater.update();
    }

    @Override
    public CaseInfoDto loadCaseInfo(String uuid) {
        CaseInfoDtoLoader loader = new CaseInfoDtoLoader(uuid);
        return loader.load();
    }

    @Override
    public CaseImageListDto loadImageList(String uuid, boolean result) {
        CaseImageListDto listDto = new CaseImageListDto();
        List<CaseImage> imageList = imageMapper.findImagesByCaseUuid(uuid, result);
        List<String> images = listDto.getImages();
        for (CaseImage caseImage : imageList) {
            images.add(caseImage.getUrl());
        }
        return listDto;
    }

    @Override
    public CaseRecordsListDto loadRecords(String uuid) {
        CaseRecordsListDto listDto = new CaseRecordsListDto();
        List<CaseRecordDto> list = listDto.getList();
        List<CaseRecord> records = recordMapper.findListByCaseUuid(uuid);
        for (CaseRecord record : records) {
            list.add(new CaseRecordDto(record));
        }
        return listDto;
    }

    @Override
    public CaseCommentListDto loadComments(String uuid) {
        CaseCommentListDto listDto = new CaseCommentListDto();
        List<CaseCommentDto> dtoList = listDto.getList();
        List<CaseComments> list = commentsMapper.findListByCaseUuid(uuid);
        for (CaseComments comments : list) {
            dtoList.add(new CaseCommentDto(comments));
        }
        listDto.setCaseUuid(uuid);
        return listDto;
    }

    @Override
    public JsonDto submitComments(CaseCommentFormDto formDto) {
        CaseCommentCreator creator = new CaseCommentCreator(formDto);
        creator.create();
        JsonDto jsonDto = new JsonDto();
        jsonDto.setState(true);
        return jsonDto;
    }

    @Override
    public CaseCommentDto disableComments(String uuid) {
        CaseComments comments = commentsMapper.selectByPrimaryKey(uuid);
        comments.setDisable(!comments.getDisable());
        commentsMapper.updateByPrimaryKeySelective(comments);

        return new CaseCommentDto(comments);
    }

    @Override
    public CaseCategoryChangeFormDto loadChangeCategoryForm(String uuid) {
        CaseCategoryChangeFormDtoLoader loader = new CaseCategoryChangeFormDtoLoader(uuid);
        return loader.load();
    }

    @Override
    public JsonDto changeCategory(CaseCategoryChangeFormDto formDto) {
        String uuid = formDto.getUuid();
        Case aCase = mapper.selectByPrimaryKey(uuid);
        String categoryUuid = formDto.getCategoryUuid();
        aCase.setCaseCategoryUuid(categoryUuid);
        mapper.updateByPrimaryKey(aCase);
        CaseCategory category = caseCategoryMapper.selectByPrimaryKey(categoryUuid);
        JsonDto jsonDto = new JsonDto();
        jsonDto.setState(true);
        String name = category.getName();
        if (name.length() > 10) {
            name = name.substring(0, 9) + "...";
        }
        jsonDto.setMsg(name);
        return jsonDto;
    }

    @Override
    public CaseReportFormDto loadReportForm(String uuid) {
        CaseReportFormDto formDto = new CaseReportFormDto(uuid);
        List<ReplySetDto> replySetList = formDto.getReplySetList();
        List<ReplySet> replySets = replySetMapper.findAll();
        for (ReplySet replySet : replySets) {
            replySetList.add(new ReplySetDto(replySet));
        }
        return formDto;
    }

    @Override
    public JsonDto reportCase(CaseReportFormDto formDto) {
        CaseReporter reporter = new CaseReporter(formDto);
        return reporter.update();
    }

    @Override
    public CaseDto loadContent(String uuid) {
        Case aCase = mapper.selectByPrimaryKey(uuid);
        return new CaseDto(aCase);
    }

    @Override
    public boolean checkUnModify(String caseUuid) {
        Case aCase = mapper.selectByPrimaryKey(caseUuid);
        CaseStatus status = aCase.getStatus();
        return status.isFinish() || status.isCancelled();
    }

    @Override
    public JsonDto cancelCase(CaseCancelFormDto formDto) {
        CaseCanceler canceler = new CaseCanceler(formDto);
        return canceler.update();
    }

    @Override
    public JsonDto finishCase(CaseFinishFormDto formDto) {
        CaseFinisher finisher = new CaseFinisher(formDto);
        return finisher.update();
    }

    @Override
    public CaseAssignmentFormDto loadAssignmentForm(String caseUuid, String deptUuid) {
        CaseAssignmentFormDto formDto = new CaseAssignmentFormDto(caseUuid, deptUuid);
        //如果部门为空,则使用当前账号的部门作为父级部门
        if (StringUtils.isEmpty(deptUuid)) {
            Employee employee = SessionUtils.getAttribute(Employee.class, SessionConstants.EMPLOYEE_KEY);
            if (employee != null) {
                deptUuid = employee.getDeptUuid();
            }
        }
        if (StringUtils.isNotEmpty(deptUuid)) {
            formDto.setCurrentDept(new DeptDto(deptMapper.selectByPrimaryKey(deptUuid)));
        }
        //加载部门
        List<DeptDto> deptList = formDto.getDeptList();
        List<Dept> listChildDept = deptMapper.findListChildDept(deptUuid);
        for (Dept dept : listChildDept) {
            deptList.add(new DeptDto(dept));
        }
        //加载部门下的员工
        if (StringUtils.isNotEmpty(deptUuid)) {
            List<EmployeeDto> dtoList = formDto.getEmployeeList();
            List<Employee> employeeList = employeeMapper.getListByDeptUuid(deptUuid);
            for (Employee employee : employeeList) {
                dtoList.add(new EmployeeDto(employee));
            }
        }
        return formDto;
    }

    @Override
    public JsonDto assignmentCase(CaseAssignmentFormDto formDto) {
        CaseAssignment assignment = new CaseAssignment(formDto);
        return assignment.update();
    }

    @Override
    public CaseAccusationFrontFromDto loadFrontFromDto(String request) {
        CaseAccusationFrontFromDtoLoader loader = new CaseAccusationFrontFromDtoLoader(request);
        return loader.load();
    }

    @Override
    public String accusationCaseFront(CaseAccusationFrontFromDto formDto) {
        CaseAccusationFrontFromDtoUpdator updator = new CaseAccusationFrontFromDtoUpdator(formDto);
        return updator.updateFront();
    }

    @Override
    public void getMyCaseFrontList(MyCaseFrontListDto listDto) {
        Member currentMember = (Member) SessionUtils.getCurrentMember();
        if (currentMember != null) {
            listDto.setCreatorUuid(currentMember.getUuid());
        }
        listDto.addAllList(mapper.getFrontList(listDto));
    }

    @Override
    public CaseFrontInfoDto loadFrontInfo(String uuid) {
        CaseFrontInfoDtoLoader loader = new CaseFrontInfoDtoLoader(uuid);
        return loader.load();
    }

    @Override
    public CaseCommentSubmitJsonDto submitFrontComments(CaseCommentFormDto formDto) {
        CaseCommentCreator creator = new CaseCommentCreator(formDto);
        CaseComments comments = creator.create();
        CaseCommentSubmitJsonDto result = new CaseCommentSubmitJsonDto(comments);
        result.setState(true);
        return result;
    }

    @Override
    public CaseAssignmentFrontFormDto loadAssignmentFrontForm(String caseUuid, String deptUuid) {
        CaseAssignmentFrontFormDto formDto = new CaseAssignmentFrontFormDto(caseUuid, deptUuid);
        //如果部门为空,则使用当前账号的部门作为父级部门
        if (StringUtils.isEmpty(deptUuid)) {
            Employee employee = SessionUtils.getAttribute(Employee.class, SessionConstants.EMPLOYEE_KEY);
            if (employee != null) {
                deptUuid = employee.getDeptUuid();
            }
        }
        if (StringUtils.isNotEmpty(deptUuid)) {
            formDto.setCurrentDept(new DeptDto(deptMapper.selectByPrimaryKey(deptUuid)));
        }

        //加载部门
        List<DeptDto> deptList = formDto.getDeptList();
        List<Dept> listChildDept = deptMapper.findListChildDept(deptUuid);
        for (Dept dept : listChildDept) {
            deptList.add(new DeptDto(dept));
        }
        //加载部门下的员工
        if (StringUtils.isNotEmpty(deptUuid)) {
            List<EmployeeDto> dtoList = formDto.getEmployeeList();
            List<Employee> employeeList = employeeMapper.getListByDeptUuid(deptUuid);
            for (Employee employee : employeeList) {
                dtoList.add(new EmployeeDto(employee));
            }
        }
        return formDto;
    }

    @Override
    public CasePendingFormDto loadPendingForm(String uuid) {
        CasePendingFormDtoLoader loader = new CasePendingFormDtoLoader(uuid);
        return loader.load();
    }

    @Override
    public CaseStatus getCaseStatus(String caseUuid) {
        Case aCase = mapper.selectByPrimaryKey(caseUuid);
        return aCase.getStatus();
    }

    @Override
    public JsonDto pendingCase(CasePendingFormDto formDto) {
        CasePendingFormDtoUpdator updator = new CasePendingFormDtoUpdator(formDto);
        return updator.update();
    }

    @Override
    public CaseProfileDto loadCaseProfile() {
        CaseProfileDto profileDto = new CaseProfileDto();

        CaseListDto caseListDto = new CaseListDto();
        caseListDto.setListStatus(CaseListStatus.UN_COMPLETE);
        this.loadCaseList(caseListDto);
        profileDto.setUnComplete(caseListDto.getTotalRecord());

        caseListDto.setListStatus(CaseListStatus.PENDING);
        this.loadCaseList(caseListDto);
        profileDto.setPending(caseListDto.getTotalRecord());

        caseListDto.setListStatus(CaseListStatus.LOCK);
        this.loadCaseList(caseListDto);
        profileDto.setLock(caseListDto.getTotalRecord());

        return profileDto;
    }

    @Override
    public CaseFinishFrontFormDto loadFinishFrontForm(String uuid) {
        Setting setting = settingMapper.findSetting();
        String currentUrl = Config.getDomainUrl() + "front/cmc/case/finish?uuid=" + uuid;
        JsSDKSignature jsSDKSignature = new JsSDKSignature(currentUrl, setting.getAppid(), setting.getSecret());
        CaseFinishFrontFormDto formDto = new CaseFinishFrontFormDto(uuid);
        formDto.setJsSDKSignature(jsSDKSignature);
        return formDto;
    }
}
